home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / ZIP191SR.ZIP / src / infozip / zip19p1 / match.s < prev    next >
Text File  |  1993-09-04  |  6KB  |  148 lines

  1. /* */
  2. /* Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly, */
  3. /* Kai Uwe Rommel and Igor Mandrichenko. */
  4. /* Permission is granted to any individual or institution to use, copy, or */
  5. /* redistribute this software so long as all of the original files are included */
  6. /* unmodified, that it is not sold for profit, and that this copyright notice */
  7. /* is retained. */
  8. /* */
  9. /* match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel. */
  10. /* syntax changed for gas 2.1.1 by DJ Delorie dj@ctron.com */
  11.  
  12. /* match.s, optimized version of longest_match() in deflate.c */
  13. /* This version is for 386 Unix or OS/2 in 32 bit mode. */
  14. /* Warning: it uses the AT&T syntax: mov source,dest */
  15. /* This file is only optional. If you want to force the C version, */
  16. /* add -DNO_ASM to CFLAGS in makefile and remove match.o from OBJI). */
  17. /* If you have reduced WSIZE in zip.h, then change its value below. */
  18. /* This version assumes static allocation of the arrays (-DDYN_ALLOC not used). */
  19.  
  20.     .file   "match.s"
  21.  
  22. #if defined(__GO32__) && defined(unix)
  23. #  undef unix
  24. #endif
  25.  
  26. #ifdef unix
  27. #  define _prev             prev
  28. #  define _window           window
  29. #  define _match_start        match_start
  30. #  define _prev_length        prev_length
  31. #  define _good_match        good_match
  32. #  define _strstart        strstart
  33. #  define _max_chain_length max_chain_length
  34.  
  35. #  define _match_init       match_init
  36. #  define _longest_match    longest_match
  37. #endif
  38.  
  39. #define MAX_MATCH     258
  40. #define MAX_MATCH2      128     /* MAX_MATCH/2-1 */
  41. #define MIN_MATCH    3
  42. #define WSIZE         32768
  43. #define MAX_DIST     WSIZE - MAX_MATCH - MIN_MATCH - 1
  44.  
  45.     .globl    _match_init
  46.     .globl  _longest_match
  47.  
  48.     .text
  49.  
  50. _match_init:
  51.     ret
  52.  
  53. /* ----------------------------------------------------------------------- */
  54. /* Set match_start to the longest match starting at the given string and */
  55. /* return its length. Matches shorter or equal to prev_length are discarded, */
  56. /* in which case the result is equal to prev_length and match_start is */
  57. /* garbage. */
  58. /* IN assertions: cur_match is the head of the hash chain for the current */
  59. /*   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 */
  60.  
  61. _longest_match:    /* int longest_match(cur_match) */
  62.  
  63. #define cur_match   20(%esp)
  64.         /* return address                / esp+16 */
  65.         push    %ebp                    /* esp+12 */
  66.         push    %edi                    /* esp+8 */
  67.     push    %esi                    /* esp+4 */
  68.     push    %ebx            /* esp */
  69.  
  70. /*       match        equ esi */
  71. /*       scan         equ edi */
  72. /*       chain_length equ ebp */
  73. /*       best_len     equ ebx */
  74. /*       limit        equ edx */
  75.  
  76.     mov     cur_match,%esi
  77.         mov     _max_chain_length,%ebp  /* chain_length = max_chain_length */
  78.     mov     _strstart,%edi
  79.     mov     %edi,%edx
  80.     sub    $(MAX_DIST),%edx         /* limit = strstart-MAX_DIST */
  81.     jae    limit_ok
  82.     sub    %edx,%edx               /* limit = NIL */
  83. limit_ok:
  84.         add    $_window+2,%edi         /* edi = offset(window + strstart + 2) */
  85.         mov    _prev_length,%ebx       /* best_len = prev_length */
  86.         movw     -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
  87.         movw     -2(%edi),%cx            /* cx = scan[0..1] */
  88.     cmp    _good_match,%ebx        /* do we have a good match already? */
  89.         jb      do_scan
  90.     shr     $2,%ebp                 /* chain_length >>= 2 */
  91.         jmp     do_scan
  92.  
  93.         .align  4
  94. long_loop:
  95. /* at this point, edi == scan+2, esi == cur_match */
  96.         movw    -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
  97.         movw     -2(%edi),%cx            /* cx = scan[0..1] */
  98. short_loop:
  99.         dec     %ebp                    /* --chain_length */
  100.         jz      the_end
  101. /* at this point, di == scan+2, si == cur_match, */
  102. /* ax = scan[best_len-1..best_len] and cx = scan[0..1] */
  103.         and     $(WSIZE-1), %esi
  104.         movw     _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
  105.                                         /* top word of esi is still 0 */
  106.         cmp     %edx,%esi        /* cur_match <= limit ? */
  107.         jbe     the_end
  108. do_scan:
  109.         cmpw    _window-1(%ebx,%esi),%ax /* check match at best_len-1 */
  110.         jne     short_loop
  111.         cmpw    _window(%esi),%cx       /* check min_match_length match */
  112.         jne     short_loop
  113.  
  114.         lea     _window+2(%esi),%esi    /* si = match */
  115.         mov     %edi,%eax               /* ax = scan+2 */
  116.         mov     $(MAX_MATCH2),%ecx       /* scan for at most MAX_MATCH bytes */
  117. #ifdef unix
  118.         repz;   cmpsw                   /* loop until mismatch */
  119. #else
  120.         repe;   cmpsw
  121. #endif
  122.         je      maxmatch                /* match of length MAX_MATCH? */
  123. mismatch:
  124.         movb    -2(%edi),%cl            /* mismatch on first or second byte? */
  125.         subb    -2(%esi),%cl            /* cl = 0 if first bytes equal */
  126.         xchg    %edi,%eax               /* edi = scan+2, eax = end of scan */
  127.         sub     %edi,%eax               /* eax = len */
  128.     sub    %eax,%esi               /* esi = cur_match + 2 + offset(window) */
  129.     sub    $_window+2,%esi         /* esi = cur_match */
  130.         subb    $1,%cl                  /* set carry if cl == 0 (cannot use DEC) */
  131.         adc     $0,%eax                 /* eax = carry ? len+1 : len */
  132.         cmp     %ebx,%eax               /* len > best_len ? */
  133.         jle     long_loop
  134.         mov     %esi,_match_start       /* match_start = cur_match */
  135.         mov     %eax,%ebx               /* ebx = best_len = len */
  136.         cmp     $(MAX_MATCH),%eax       /* len >= MAX_MATCH ? */
  137.         jl      long_loop
  138. the_end:
  139.         mov     %ebx,%eax               /* result = eax = best_len */
  140.     pop     %ebx
  141.         pop     %esi
  142.         pop     %edi
  143.         pop     %ebp
  144.         ret
  145. maxmatch:
  146.         cmpsb
  147.         jmp     mismatch
  148.